import random
import tkinter as tk
from tkinter import messagebox
import threading
import time
import sys
import os

# 替换 AppLogger（如果没有该模块，使用 loguru 直接日志）
from loguru import logger

# 配置 loguru 日志
logger.add("love_program.log", rotation="500 MB", retention="7 days", compression="zip")

class Program:
    # 初始化配置
    def __init__(self):
        logger.info('爱心程序初始化')
        self.colors = [
            ("red", "红色"),
            ("yellow", "黄色"),
            ("blue", "蓝色"),
            ("purple", "紫色"),
            ("white", "白色"),
            ("orange", "橙色"),
            ("pink", "粉色"),
            ("green", "绿色")
        ]
        self.love_phrases = [
            "你是我心中的唯一",
            "爱你是我做过最好的事",
            "愿与你共度每一个明天",
            "你的笑容是我最大的幸福",
            "遇见你是我最幸运的事",
            "想和你一起慢慢变老",
            "你是我最美的意外",
            "喜欢你，是我最骄傲的事",
            "愿时光不老，爱情不散",
            "你是我的小确幸",
            "爱你在每一天",
            "心中有你，处处是甜",
            "愿得一人心，白首不相离",
            "你是我最想留住的幸运",
            "爱如潮水，将我包围",
            "与你相伴，胜过人间无数",
            "你是我眼中的星辰大海",
            "爱你，是我最坚定的选择",
            "愿此生请指教",
            "你是我生命中最亮的那颗星"
        ]
        self.active_windows = []  # 存储活动窗口的列表
        self.window_lock = threading.Lock()  # 线程锁保护共享资源
        self.window_count = 0  # 窗口计数器
        self.main_root = tk.Tk()  # 主窗口（用于调度 Tkinter 任务）
        self.main_root.withdraw()  # 隐藏主窗口
        self.is_running = True  # 程序运行状态标志

    # 主程序进程
    def run(self):
        logger.info('程序开始运行')
        # 启动一个新线程来随机弹出对话框
        popup_thread = threading.Thread(target=self.random_popups)
        popup_thread.daemon = True  # 设置为守护线程
        popup_thread.start()

        # 启动主窗口的事件循环（关键：所有 Tkinter 操作都通过这个循环）
        try:
            self.main_root.mainloop()
        except KeyboardInterrupt:
            self.exit_program()

    def safe_destroy_window(self, root):
        """安全销毁窗口（通过主窗口的 after 方法在主线程执行）"""

        def destroy():
            try:
                if root.winfo_exists():  # 检查窗口是否还存在
                    root.destroy()
                # 从活动窗口列表中移除
                with self.window_lock:
                    if root in self.active_windows:
                        self.active_windows.remove(root)
                        self.window_count = max(0, self.window_count - 1)
            except Exception as e:
                logger.warning(f"销毁窗口失败: {e}")

        # 通过主窗口调度销毁操作
        if self.main_root.winfo_exists():
            self.main_root.after(0, destroy)

    def animate_window_movement_with_fade(self, root, target_x, target_y, steps=50):
        """动画移动窗口到目标位置，并伴有透明度变化（确保在窗口线程执行）"""
        try:
            if not root.winfo_exists():
                return

            # 获取当前窗口位置
            current_x = root.winfo_x()
            current_y = root.winfo_y()

            # 计算每步的移动距离
            step_x = (target_x - current_x) / steps
            step_y = (target_y - current_y) / steps

            # 执行动画移动和透明度变化
            def animate_step(i):
                if i < steps and root.winfo_exists():
                    # 移动窗口
                    new_x = int(current_x + step_x * (i + 1))
                    new_y = int(current_y + step_y * (i + 1))
                    root.geometry(f"+{new_x}+{new_y}")

                    # 透明度变化：从半透明到完全不透明
                    alpha = 0.5 + (0.5 * (i + 1) / steps)
                    root.attributes('-alpha', alpha)

                    # 调度下一步动画
                    root.after(50, animate_step, i + 1)

            # 启动动画
            root.after(0, animate_step, 0)
        except Exception as e:
            logger.warning(f"窗口动画失败: {e}")

    def move_window_randomly(self, root):
        """随机移动窗口位置（带动画和透明度效果）"""
        try:
            if not root.winfo_exists():
                return

            screen_width = root.winfo_screenwidth()
            screen_height = root.winfo_screenheight()
            window_width = root.winfo_width()
            window_height = root.winfo_height()

            # 确保窗口尺寸已经初始化
            if window_width <= 1 or window_height <= 1:
                window_width = random.randint(100, 280)
                window_height = random.randint(40, 80)
                while abs(window_width - window_height) < 20:
                    window_width = random.randint(100, 280)
                    window_height = random.randint(40, 80)
                root.geometry(f"{window_width}x{window_height}")

            # 随机选择一个目标位置
            target_x = random.randint(0, max(0, screen_width - window_width))
            target_y = random.randint(0, max(0, screen_height - window_height))

            # 执行带动画和透明度变化的移动
            self.animate_window_movement_with_fade(root, target_x, target_y)
        except Exception as e:
            logger.warning(f"随机移动窗口失败: {e}")

    def fade_in_window(self, root, steps=20):
        """实现窗口淡入效果（在窗口线程执行）"""
        try:
            if not root.winfo_exists():
                return

            def fade_step(i):
                if i <= steps and root.winfo_exists():
                    alpha = 0.1 + (0.9 * i / steps)
                    root.attributes('-alpha', alpha)
                    if i < steps:
                        root.after(50, fade_step, i + 1)

            # 启动淡入动画
            root.after(0, fade_step, 1)
        except Exception as e:
            logger.warning(f"窗口淡入失败: {e}")

    def create_colored_popup(self):
        """创建一个随机颜色的弹窗（确保在独立线程中正确初始化）"""
        try:
            # 随机选择颜色和情话
            color_info = random.choice(self.colors)
            color_name, color_chinese = color_info
            love_phrase = random.choice(self.love_phrases)

            # 生成非正方形的窗口尺寸
            window_width = random.randint(150, 300)
            window_height = random.randint(40, 100)
            while window_height >= window_width * 0.8:
                window_height = random.randint(40, 100)

            # 创建窗口（每个弹窗一个独立的 Tk 实例）
            root = tk.Tk()
            root.overrideredirect(True)  # 移除标题栏
            root.geometry(f"{window_width}x{window_height}")
            root.attributes('-alpha', 0.1)  # 初始透明度
            root.configure(bg=color_name)
            root.attributes('-topmost', True)  # 置顶

            # 选择合适的字体颜色
            if color_name in ["white", "yellow"]:
                font_color = "black"
            elif color_name in ["orange", "pink"]:
                font_color = "darkblue"
            else:
                font_color = "white"

            # 计算字体大小
            max_font_size_by_width = window_width // len(love_phrase) * 2.5
            max_font_size_by_height = window_height * 0.6
            base_font_size = max(8, min(int(max_font_size_by_width), int(max_font_size_by_height), 16))

            # 创建标签
            label = tk.Label(
                root,
                text=love_phrase,
                bg=color_name,
                fg=font_color,
                font=("Arial", base_font_size, "bold"),
                wraplength=window_width - 20,
                justify="center"
            )
            label.pack(expand=True, fill=tk.BOTH)

            # 随机初始位置
            screen_width = root.winfo_screenwidth()
            screen_height = root.winfo_screenheight()
            x = random.randint(0, max(0, screen_width - window_width))
            y = random.randint(0, max(0, screen_height - window_height))
            root.geometry(f"{window_width}x{window_height}+{x}+{y}")

            # 添加到活动窗口列表
            with self.window_lock:
                if self.is_running:
                    self.active_windows.append(root)
                    self.window_count += 1

            # 启动淡入效果
            self.fade_in_window(root)

            # 调度随机移动
            def schedule_movement():
                if root.winfo_exists() and self.is_running:
                    delay = random.randint(3000, 8000)
                    root.after(delay, self.move_window_randomly, root)

            root.after(100, schedule_movement)

            # 窗口关闭时的清理
            def on_close():
                self.safe_destroy_window(root)

            root.protocol("WM_DELETE_WINDOW", on_close)

            # 运行窗口事件循环
            root.mainloop()
        except Exception as e:
            logger.error(f"创建弹窗失败: {e}")

    def show_completion_dialog(self):
        """显示完成对话框（在主线程执行）"""

        def show_dialog():
            dialog = tk.Toplevel(self.main_root)
            dialog.title("感谢观看")
            dialog.geometry("300x150")
            dialog.attributes('-topmost', True)

            # 居中显示
            screen_width = dialog.winfo_screenwidth()
            screen_height = dialog.winfo_screenheight()
            x = (screen_width - 300) // 2
            y = (screen_height - 150) // 2
            dialog.geometry(f"300x150+{x}+{y}")

            # 添加标签
            label = tk.Label(
                dialog,
                text="谢谢你看完了，记得今天开心哦",
                font=("Arial", 12),
                wraplength=280,
                justify="center"
            )
            label.pack(expand=True, pady=20)

            # 按钮框架
            button_frame = tk.Frame(dialog)
            button_frame.pack(pady=10)

            def restart_program():
                dialog.destroy()
                # 重启程序
                with self.window_lock:
                    self.is_running = True
                    # 销毁现有窗口
                    for window in list(self.active_windows):
                        self.safe_destroy_window(window)
                    self.active_windows.clear()
                    self.window_count = 0
                # 重新启动弹窗线程
                popup_thread = threading.Thread(target=self.random_popups)
                popup_thread.daemon = True
                popup_thread.start()

            def exit_program():
                dialog.destroy()
                self.exit_program()

            # 按钮
            exit_button = tk.Button(button_frame, text="嗯，好", width=10, command=exit_program)
            exit_button.pack(side=tk.LEFT, padx=10)

            # restart_button = tk.Button(button_frame, text="再看一次", width=10, command=restart_program)
            # restart_button.pack(side=tk.RIGHT, padx=10)

            dialog.mainloop()

        # 通过主窗口调度对话框显示
        self.main_root.after(0, show_dialog)

    def exit_program(self):
        """退出程序（安全清理所有资源）"""
        logger.info("程序开始退出...")
        self.is_running = False

        # 销毁所有弹窗
        with self.window_lock:
            for window in list(self.active_windows):
                self.safe_destroy_window(window)
            self.active_windows.clear()
            self.window_count = 0

        # 销毁主窗口
        if self.main_root.winfo_exists():
            self.main_root.after(0, self.main_root.destroy)

        # 等待所有线程结束
        time.sleep(0.5)
        logger.info("程序已退出")
        os._exit(0)

    def random_popups(self):
        """随机弹出对话框（控制窗口数量）"""
        try:
            while self.is_running and self.window_count < 100:
                if not self.is_running:
                    break
                # 控制弹窗创建速度
                time.sleep(random.uniform(0.2, 0.8))
                # 创建弹窗（每个弹窗一个独立线程）
                if self.is_running:
                    popup_thread = threading.Thread(target=self.create_colored_popup, daemon=True)
                    popup_thread.start()

            # 所有弹窗创建完成后，等待一段时间
            if self.is_running:
                logger.info("弹窗创建完成，等待动画结束...")
                time.sleep(10)
                # 显示完成对话框
                if self.is_running:
                    self.show_completion_dialog()
        except Exception as e:
            logger.error(f"弹窗线程异常: {e}")
            self.exit_program()

if __name__ == '__main__':
    try:
        program = Program()
        program.run()
    except KeyboardInterrupt:
        logger.info("接收到中断信号，程序退出")
        os._exit(0)
    except Exception as e:
        logger.critical(f"程序异常退出: {e}")
        os._exit(1)
